﻿#if NETSTANDARD2_0 || NETCOREAPP3_0
using Microsoft.Extensions.Configuration;
using System.Linq;
#else
using System.Configuration;
#endif
using System;
using System.Reflection;
using System.Collections.Concurrent;

namespace Longbow.Data
{
    /// <summary>
    /// IDbContext 默认实现类
    /// </summary>
    internal class DefaultDbContext<T> : IDbContext<T> where T : class
    {
        private static readonly ConcurrentDictionary<string, T> _contextPool = new ConcurrentDictionary<string, T>();

#if NETSTANDARD2_0 || NETCOREAPP3_0
        private readonly IConfiguration _configuration;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        /// <param name="configuration">IConfiguration 实例</param>
        public DefaultDbContext(IConfiguration configuration) => _configuration = configuration;

        private static DbAdapterItem CreateAdapterItemFromConfig(IConfiguration configuration)
        {
            var option = configuration.GetSection("DB").GetChildren().Select(config => new DbAdapterItem()
            {
                Widget = config["Widget"],
                Enabled = bool.TryParse(config["Enabled"], out var en) ? en : false
            });
            return option.FirstOrDefault(i => i.Enabled);
        }
#else
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public DefaultDbContext()
        {

        }
#endif

        private T CreateInstance(string assemblyName)
        {
            T ret;
            if (!string.IsNullOrEmpty(assemblyName))
            {
                var assembly = Assembly.Load(assemblyName);
                ret = Activator.CreateInstance(assembly.GetType($"{assemblyName}.{typeof(T).Name}", true, true)) as T;
            }
            else
            {
                ret = Activator.CreateInstance<T>();
            }
            return ret;
        }

        /// <summary>
        /// 创建 T 实例方法
        /// </summary>
        /// <returns>T 实例</returns>
        public T Create()
        {
#if NETSTANDARD2_0 || NETCOREAPP3_0
            var widget = CreateAdapterItemFromConfig(_configuration);
            var t = _contextPool.GetOrAdd(widget?.Widget ?? "default", key => CreateInstance(widget?.Widget));
#else
            var widget = ConfigurationManager.AppSettings["DbWidget"];
            var t = CreateInstance(widget);
#endif
            return t;
        }

        /// <summary>
        ///
        /// </summary>
        private class DbAdapterItem
        {
            /// <summary>
            /// 获得/设置 是否启用
            /// </summary>
            public bool Enabled { get; set; }

            /// <summary>
            /// 获得/设置 插件描述 动态链接库名称
            /// </summary>
            public string Widget { get; set; }
        }
    }
}
